#统计股票日内波动，生成波动量和波动宽度
StatFun<-function(Data){
  #数据预处理，消除NA数据和0数据
  for (j in 2:(length(Data)))  #向前填充，需要第一个值非0
  {
    if(Data[j]==0)
      Data[j] = Data[j-1]; 
  }
  for (j in (length(Data)-1):1) #向后填充，需要最后一个值非0
  {
    if(Data[j]==0)
      Data[j] = Data[j+1]; 
  }
  Data = Data[Data!=0]  #消除0数据
  
  #统计Data的drawdown
  PPos<-c();  #上一个极大值
  NPos<-c();  #上一个极小值
  LstPos<-1;
  #波动和宽度
  wave = data.frame(matrix(vector(), 0, 2, dimnames=list(c(), c("Fluc", "Width"))), stringsAsFactors=F)
  k <- 1;
  if(length(Data)>2) #每日至少三个收盘价
  {
    for(i in 2:(length(Data)-1)){
      #极大值 (大于上一个极小值，并小于下一个值)
      if(Data[i]>Data[LstPos]&& Data[i]>Data[i+1]){  
		wave[k,] = c((Data[i]-Data[LstPos])/Data[LstPos], i-LstPos)
        k = k+1
        LstPos<-i;      
      }
      #极小值 (小于上一个极大值,并大于下一个值)
      if((Data[i]<Data[LstPos])&& (Data[i]<Data[i+1])){  
        wave[k,] = c((Data[i]-Data[LstPos])/Data[LstPos], i-LstPos)
        k = k+1
        LstPos<-i;
      }
    }
  } else
  {
    LstPos=1; #将最初值设置为第一个，最后一个值设置为最终值
    i=length(Data);    
  }
  
  #最后一个值
  wave[k,] = c((Data[i]-Data[LstPos])/Data[LstPos], i-LstPos)
  k = k+1
  
  width.mean = mean(wave$Width)
  width.sd = sd(wave$Width)
  
  fluc.sel = subset(wave$Fluc, wave$Width>(width.mean-width.sd))
  fluc.mean = mean(fluc.sel)
  fluc.sd = sd(fluc.sel)

  wave.summary = list(fluc.mean=fluc.mean, fluc.sd=fluc.sd, width.mean=width.mean, width.sd=width.sd)
  return(wave.summary);
}

#处理股票日内，获取统计数据
#读入矩阵数据，输出统计list
sta.stock<- function(Stock.intra.list){
  Stock.symbol = names(Stock.intra.list)
  #将所有股票的日期汇总
  Stock.date = c()
  for(i in 1:length(Stock.symbol)){
    Stock.date = sort(unique(c(Stock.date, Stock.intra.list[[Stock.symbol[i]]]$date)))
  }

  #产生 指数每日波动数据统计量
  sta.list <- matrix(nrow=length(Stock.date), ncol=length(Stock.symbol))
  colnames(sta.list) <- Stock.symbol
  rownames(sta.list) <- as.character(as.Date(as.character(Stock.date),"%Y%m%d"))
  #rownames(sta.list) <- lapply(Stock.date, as.Date.character, '%Y%m%d',simplify=TRUE)
  for(i in 1:length(Stock.symbol)){
    print(i)
    Stock.intra <- split(Stock.intra.list[[Stock.symbol[i]]],Stock.intra.list[[Stock.symbol[i]]]$date); #按照日期分割日内数据
    Stock.date.symbol = names(Stock.intra)
    for (j in 1:length(Stock.date.symbol))
    {
      #print(j)
      Stock.oneday = Stock.intra[[Stock.date.symbol[j]]]
      Stock.oneday.price = Stock.oneday$CLOSE;
      
      if(sum(Stock.oneday.price)==0) #数据全部缺失,利用上个值填充
      {
        wave.oneday = NA
      } else{
        if(length(Stock.oneday.price)<2) #可能是停盘
          wave.oneday = list(fluc.mean=prev.fluc.mean, fluc.sd=prev.fluc.sd, width.mean=prev.width.mean, width.sd=prev.width.sd) #设置为涨幅前一日，此处需要修正
        else
          wave.oneday = StatFun(Stock.oneday.price)
      }
      sta.list[as.character(as.Date(Stock.date.symbol[j],"%Y%m%d")),Stock.symbol[i]] = prev.fluc.mean = wave.oneday$fluc.mean
    }
  }
  return(sta.list)
}

#生成12日ema
#输入为矩阵，输出为矩阵
ema.12 <- function(data){
  sum = 0 
  ema = matrix(nrow=nrow(data), ncol=ncol(data),dimnames=list(rownames(data),colnames(data)))
  
  ema[1,] = data[1,]
  for (i in 2:nrow(data))
  {
    data.one.row = data[i,]
    data.last.row = data[i-1,]
    data.last.row[is.na(data.last.row)] = data.one.row[is.na(data.last.row)] # 用上一个值弥补当前NA值
    ema[i,] = 7/13*data[i,] + 6/13*data[i,] 
  }
  
  ema.col = colnames(ema)
  for(i in 1:length(ema.col))
  {
  if(sum(is.na(ema[,ema.col[i]]))>1/6*nrow(ema))
  	#ema = ema[,-ema.col[i]]
	subset(ema, select = -ema.col[            i])
  }
  return(ema)
}


#获取沪深300日内数据,比如"index\\sh000300_2006.csv"
sta.idx<- function(idx.intra.list){
  #产生 指数每日波动数据统计量
  idx.intra.list.date <- names(idx.intra.list)
  Date.length <- length(idx.intra.list.date)
  idx.sta <- list()
  for(i in 1:(Date.length)){
    print(i)
    idx.sz1.oneday = idx.intra.list[[idx.intra.list.date[i]]];
    idx.sz1.price = idx.sz1.oneday$最新;
    
    if(sum(idx.sz1.price)==0) #数据全部缺失,利用上个值填充
    {
      wave.oneday = list(fluc.mean=prev.fluc.mean, fluc.sd=prev.fluc.sd, width.mean=prev.width.mean, width.sd=prev.width.sd) #设置为涨幅无穷大
    } else{
      idx.wave.oneday = StatFun(idx.sz1.price)
    }
    
    idx.sta[[idx.intra.list.date[i]]]$fluc.mean = prev.fluc.mean = idx.wave.oneday$fluc.mean
    idx.sta[[idx.intra.list.date[i]]]$fluc.sd = prev.fluc.sd = idx.wave.oneday$fluc.sd
    idx.sta[[idx.intra.list.date[i]]]$width.mean = prev.width.mean = idx.wave.oneday$width.mean
    idx.sta[[idx.intra.list.date[i]]]$width.sd = prev.width.sd = idx.wave.oneday$width.sd
  }
  return(idx.sta)
}
